import SceneBase from "../core/bases/SceneBase";
import { Messages } from "../core/constants/Messages";
import MathUtil from "../core/utils/MathUtil";
import MgrAudio from "./MgrAudio";

const { ccclass, property } = cc._decorator;

@ccclass
export default class main extends SceneBase {

    @property(cc.Node)
    giftBoxNode: cc.Node = null;

    @property(cc.Sprite)
    pgBarSpr: cc.Sprite = null;
    @property(cc.Label)
    pgLab: cc.Label = null;

    @property(cc.Node)
    bonusNode: cc.Node = null;

    @property(cc.Node)
    btnOpenGift: cc.Node = null;
    @property(cc.Label)
    introLab: cc.Label = null;

    _lastAccVal: number = -999;

    _curPg: number = 0;
    _pgDecPerDt: number = .01;

    _giftBoxOriPos: cc.Vec2 = cc.v2();
    _giftBoxMoveThreshold: number = .2;
    _giftBoxMoveFlag: boolean = false;
    _giftBoxOffsetRange: number = 12;

    _openGiftClicked: boolean = false;

    _shakeTime: number = 0;
    _isGiftThrilling: boolean = false;

    onLoad() {
        super.onLoad();

        if (cc.sys.isMobile) {
            cc.systemEvent.on(cc.SystemEvent.EventType.DEVICEMOTION, this.onDeviceMotionEvent, this);
        } else {// is PC
            cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);

            this.introLab.string = "狂按空格，打开礼盒！"
        }

        this.btnOpenGift.on(cc.Node.EventType.TOUCH_START, this.onOpenGiftClick, this);
    }

    start() {
        super.start();
        cc.game.setFrameRate(59);

        this.pgBarSpr.fillRange = 0;
        this.giftBoxNode.getPosition(this._giftBoxOriPos);
    }

    onOpenGiftClick() {
        if (this._openGiftClicked) return;
        this._openGiftClicked = true;
        this.btnOpenGift.emit(Messages.Nodes.StateChangePause);
        cc.tween(this.btnOpenGift).to(.2, { scale: .9 }, { easing: "cubicOut" }).to(.2, { scale: 1 }, { easing: "cubicOut" })
            .call(() => {
                this.pgBarSpr.node.parent.active = true;
                this.introLab.node.active = true;
            }).to(.2, { opacity: 0 }, { easing: "cubicOut" }).start();

        cc.systemEvent.setAccelerometerEnabled(true);
    }

    onDeviceMotionEvent(event: cc.Event.EventAcceleration) {
        if (!this._openGiftClicked) return;
        if (this._lastAccVal != -999 && this._curPg < 1) {
            let offset = Math.abs(this._lastAccVal - (event.acc.x + event.acc.y + event.acc.z));
            if (offset > this._giftBoxMoveThreshold) {
                this._shakeTime = .2;
                this._addOpenProgress(offset * .05);
            }
        }
        this._lastAccVal = event.acc.x + event.acc.y + event.acc.z;
    }

    onKeyDown(event: cc.Event.EventKeyboard) {
        if (!this._openGiftClicked) return;
        if (event.keyCode == cc.macro.KEY.space) {
            this._addOpenProgress(.05);
        }
    }

    _addOpenProgress(add: number) {
        this._onThrillGift();
        this._curPg += add;
        if (this._curPg > 1) {
            this._curPg = 1;

            this._updatePg();
            this._onOpenGift();

            cc.systemEvent.setAccelerometerEnabled(false);
            cc.systemEvent.off(cc.SystemEvent.EventType.DEVICEMOTION);
        }
    }

    update(dt: number) {
        if (this._curPg >= 1) return;
        if (this._shakeTime > 0) this._shakeTime -= dt;
        this._updatePg();
    }

    _updatePg() {
        this.pgBarSpr.fillRange = this._curPg;
        this.pgLab.string = Math.round(this._curPg * 100) + "%";
    }

    _onThrillGift(autoThrill: boolean = true, dura: number = .2) {
        if (this._isGiftThrilling) return;
        this._isGiftThrilling = true;
        MgrAudio.Instance.forcePlayMusic(1);
        let step = Math.ceil(this._curPg / .2);
        let range = MathUtil.randomRangeFloat(step - 1, step) * this._giftBoxOffsetRange;
        let dire = Math.PI * 2 * Math.random();
        let offx = range * Math.cos(dire), offy = range * Math.sin(dire);
        this.giftBoxNode.stopAllActions();
        this.giftBoxNode.setPosition(this._giftBoxOriPos);
        cc.tween(this.giftBoxNode).by(dura, { x: offx, y: offy }).by(dura * 2, { x: -2 * offx, y: -2 * offy })
            .by(dura, { x: offx, y: offy }).call(() => {
                this._isGiftThrilling = false;
                autoThrill && this._shakeTime > 0 && this._onThrillGift();
            }).start();
    }

    _onOpenGift() {
        cc.tween(this.pgBarSpr.node.parent).to(.3, { opacity: 0 }, { easing: "cubicOut" }).start();
        cc.tween(this.introLab.node).to(.3, { opacity: 0 }, { easing: "cubicOut" }).start();
        let times = [.1, .09, .08, .06, .05, .03, .03, .03, .03, .03, .03, .03, .03, .03, .03, .03, .03, .03, .03, .03];
        let timeAdd = 0;
        times.forEach(v => {
            this.scheduleOnce(this._onThrillGift.bind(this, false, v), timeAdd);
            timeAdd += v * 4;
        });
        this.scheduleOnce(() => {
            MgrAudio.Instance.PlayMusic(2);
            cc.tween(this.giftBoxNode).to(.2, { opacity: 0, scale: 2 }, { easing: "cubicOut" })
                .call(() => {
                    this.giftBoxNode.active = false;
                    this.pgBarSpr.node.parent.active = false;
                    this.introLab.node.active = false;
                }).start();
            this.bonusNode.active = true;
        }, timeAdd);
    }

}